package com.ruoyi.web.controller.common;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.ServerConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.OnlineStatus;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.framework.shiro.service.SysLoginService;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.web.controller.common.dto.IntegratedAuthenticationDto;
import com.ruoyi.web.controller.common.dto.SyncUserDto;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 集成系统访问
 *
 * @author ruoyi
 */
@Controller
@RequestMapping("integrated/visit")
public class IntegratedVisitController extends BaseController {
    @Value("${integrated.appId}")
    private String appId;

    @Value("${integrated.appSecret}")
    private String appSecret;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysUserOnlineService userOnlineService;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private SysPasswordService passwordService;

    /**
     * 默认密码
     */
    @Value("${admin.pwd}")
    private String adminPwd;

    private final static String KEY = "integrated_access_token";

    /**
     * 认证
     *
     * @return
     */
    @Anonymous
    @ResponseBody
    @PostMapping("authentication")
    public IVResult authentication(@RequestBody IntegratedAuthenticationDto dto) throws Exception {

        // 校验
        String msg = verify(dto);
        if (msg == null) {
            String access_token = IdUtils.fastSimpleUUID();
            CacheUtils.put(KEY, access_token);
            //access_token 保存到缓存中
            return IVResult.success(serverConfig.getUrl() + "/integrated/visit/index?access_token=" + access_token);
        } else {
            return IVResult.error(msg);
        }
    }

    // 校验
    private String verify(IntegratedAuthenticationDto dto) throws Exception {
        JSONObject json = JSONObject.parseObject(AESUtil.decrypt(appSecret, dto.getAccessToken()));
        if (!appId.equals(json.getString("appId"))) {
            return "appID不一致";
        }
        long jTime = json.getLongValue("time");
        long time = new Date().getTime();
        if (jTime > time || time - jTime > 10000) {
            return "请求时间误差过大";
        }
        return null;
    }

    /**
     * 访问页面
     *
     * @param access_token 认证token
     * @param page         页面标识
     * @return
     */
    @GetMapping("index")
    public String index(@RequestParam String access_token, @RequestParam("user") String username, @RequestParam String page) {
        //解析 access_token
        String cToken = (String) CacheUtils.get(KEY);
        if (StringUtils.isEmpty(cToken) || !cToken.equals(access_token)) {
            return ServletUtils.renderString(ServletUtils.getResponse(), "用户未认证");
        }
        SysUser sysUser = userService.selectUserByLoginName(username);
        if (Objects.isNull(sysUser)) {
            return ServletUtils.renderString(ServletUtils.getResponse(), "未获取到用户信息");
        }

        //建立在线会话
        Date startTimestamp = new Date();
        String loginIp = sysUser.getLoginIp();
        String loginName = sysUser.getLoginName();

        SysUserOnline online = new SysUserOnline();
        online.setSessionId(sysUser.getUserId() + "");
        online.setDeptName(sysUser.getDept().getDeptName());
        online.setLoginName(loginName);
        online.setStartTimestamp(startTimestamp);
        online.setLastAccessTime(startTimestamp);
        online.setExpireTime(1800000L);
        online.setIpaddr(loginIp);
        online.setLoginLocation(AddressUtils.getRealAddressByIP(loginIp));
        online.setStatus(OnlineStatus.on_line);
        userOnlineService.saveOnline(online);
        //TODO:需要获取当前用户对应的菜单进行比对
        //登录
        String pwd = adminPwd; //passwordService.encryptPassword(loginName, adminPwd, sysUser.getSalt());
        UsernamePasswordToken token = new UsernamePasswordToken(username, pwd, false);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return page;
        } catch (AuthenticationException e) {
            String msg = "用户或密码错误";
            if (StringUtils.isNotEmpty(e.getMessage())) {
                msg = e.getMessage();
            }
            return ServletUtils.renderString(ServletUtils.getResponse(), "第三方系统登录失败");
        }
    }

    /**
     * 用户同步
     *
     * @param dto
     * @return
     */
    @Anonymous
    @ResponseBody
    @PostMapping("syncUser")
    public AjaxResult syncUser(@RequestBody SyncUserDto dto) {
        List<SysUser> userList = dto.getUserList();
        if (CollectionUtils.isEmpty(userList)) {
            return AjaxResult.error("未获取到用户信息");
        }
        for (SysUser user : userList) {
            SysUser sysUser = userService.selectUserByLoginName(user.getUserName());
            if (Objects.isNull(sysUser)) {
                user.setSalt(ShiroUtils.randomSalt());
                user.setPassword(passwordService.encryptPassword(user.getLoginName(), adminPwd, user.getSalt()));
                userService.insertUser(user);
            } else {
                userService.updateUser(user);
            }
        }
        //        userService.importUser(userList,true,"sysAdmin");
        return AjaxResult.success();
    }


}
